unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Buttons, ExtCtrls, StdCtrls,about, Menus;

type
  TForm1 = class(TForm)
    Image1: TImage;
    SpeedButton1: TSpeedButton;
    SpeedButton2: TSpeedButton;
    Edit1: TEdit;
    SpeedButton4: TSpeedButton;
    SpeedButton5: TSpeedButton;
    SpeedButton6: TSpeedButton;
    SpeedButton7: TSpeedButton;
    OpenDialog1: TOpenDialog;
    SaveDialog1: TSaveDialog;
    Timer1: TTimer;
    MainMenu1: TMainMenu;
    NewTree1: TMenuItem;
    Options1: TMenuItem;
    About1: TMenuItem;
    Close1: TMenuItem;
    Load1: TMenuItem;
    Save1: TMenuItem;
    Delete1: TMenuItem;
    Delete2: TMenuItem;
    Animation1: TMenuItem;
    NahradMaxZLava1: TMenuItem;
    NahradMinZPrava1: TMenuItem;
    Noanimation1: TMenuItem;
    Krokom1: TMenuItem;
    Animacia1: TMenuItem;
    Speed1: TMenuItem;
    N11: TMenuItem;
    N21: TMenuItem;
    N31: TMenuItem;
    N41: TMenuItem;
    N51: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure SpeedButton1Click(Sender: TObject);
    procedure SpeedButton2Click(Sender: TObject);
    procedure SpeedButton4Click(Sender: TObject);
    procedure SpeedButton5Click(Sender: TObject);
    procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure Image1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure SpeedButton7Click(Sender: TObject);
    procedure SpeedButton6Click(Sender: TObject);
    procedure Edit1KeyPress(Sender: TObject; var Key: Char);
    procedure Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure Close1Click(Sender: TObject);
    procedure Save1Click(Sender: TObject);
    procedure Load1Click(Sender: TObject);
    procedure NewTree1Click(Sender: TObject);
    procedure About1Click(Sender: TObject);
    procedure NahradMaxZLava1Click(Sender: TObject);
    procedure NahradMinZPrava1Click(Sender: TObject);
    procedure Noanimation1Click(Sender: TObject);
    procedure Krokom1Click(Sender: TObject);
    procedure Animacia1Click(Sender: TObject);
    procedure N51Click(Sender: TObject);
    procedure N41Click(Sender: TObject);
    procedure N31Click(Sender: TObject);
    procedure N21Click(Sender: TObject);
    procedure N11Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    function checkInteger(text: string):boolean;
    procedure Settings;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  myAVL;

var
  strom: AVLStrom;
  path: string;
  optionsDelete,tempDelete:integer;
  new: boolean; //test ci je novy strom

procedure TForm1.Animacia1Click(Sender: TObject);
begin
  Noanimation1.Checked:=false;
  Krokom1.Checked:=false;
  Animacia1.Checked:=true;
  Speed1.Visible:=true;
  strom.setAnimation(3);
end;

function TForm1.checkInteger(text: string): boolean;    // zistenie spravnosti vstupu
var
  i: integer;
begin
   result := true;
    for i := 1 to Length(text) do
    if not (text[i] in ['0'..'9']) then
      result := false;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
     Settings;
     optionsDelete:=1;
     tempDelete:=1;
     new:=true;
     path:=ExtractFilePath(ParamStr(0));
    // vytvori strom, ako vstup ide: canvas, dlzka canvasu, vyska canvasu
    strom:= AVLStrom.create(Image1,Image1.width, Image1.Height);
    strom.kresli;       //nakresli "nil" strom
    timer1.Enabled:=false;
end;



procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  strom.dragging(X,Y,'click');
end;

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  strom.dragging(X,Y,'drag');
end;

procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  strom.dragging(X,Y,'stop');
end;

procedure TForm1.Krokom1Click(Sender: TObject);
begin
  Noanimation1.Checked:=false;
  Krokom1.Checked:=true;
  Animacia1.Checked:=false;
  Speed1.Visible:=false;
  strom.setAnimation(2);
end;

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var
  isInt: boolean;
begin
  if Key= VK_RETURN then begin
    if Edit1.Text<>'' then begin
      isInt:=checkInteger(edit1.text);
      if isInt then begin
        if strtoint(edit1.text)>200 then begin
          ShowMessage('Too big Input');
          strom.kresli;
        end else if strtoint(edit1.text)>200 then
          ShowMessage('Bad input')
        else begin
          timer1.Enabled:=true;
          if (strtoint(edit1.text)>0) AND (strom.vloz(strtoint(edit1.text))) then begin
            strom.Back(strtoint(edit1.text),0);
            new:=false;
          end;
          timer1.Enabled:=false;
        end;
      end
      else
        ShowMessage('Bad input');
      edit1.Clear;
    end else
      ShowMessage('Bad input');
  end;
  if Key=VK_F1 then begin
    strom.clear;
    setlength(strom.navrat,0);
    new:=true;
    optionsDelete:=tempDelete;
    edit1.Clear;
  end;
  if Key=VK_F2 then begin
    savedialog1.InitialDir:=path;
    if (length(strom.navrat)>0) AND (savedialog1.Execute) then
      strom.save(optionsDelete,savedialog1.FileName)
    else
      ShowMessage('Empty Tree cannot save');
    edit1.Clear;
  end;
  if Key=VK_F3 then begin
    opendialog1.InitialDir:=path;
    if opendialog1.Execute  then
      strom.load(opendialog1.FileName);
    edit1.Clear;
  end;
end;


procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
var
  _random,temp:integer;
begin
  if (Key= 'd') OR (Key='D') then begin   //delete
    if Edit1.Text<>'' then begin
      if (strtoint(edit1.text)>0) AND
        (strom.Zrus(optionsDelete,strtoint(edit1.text))) then
        strom.Back(-1*strtoint(edit1.text),0);
      edit1.clear;
    end else
      ShowMessage('Bad input');
  end;
  if (Key='b') OR (Key='B') then begin //back
    temp:=strom.setAnimation(1);
    strom.Back(0,optionsDelete);
    strom.kresli;
    strom.setAnimation(temp);
    edit1.clear;
  end;
  if (Key='h') OR (Key='H')  then begin  //member
    if edit1.Text<>'' then begin
      if checkInteger(edit1.text) then
        strom.Hladaj(strtoint(edit1.text)) else
        ShowMessage('Bad input');
      edit1.Clear;
    end else
      ShowMessage('Bad input');
  end;
  if (Key='n') OR (Key='N') then begin // novy strom
    strom.clear;
    setlength(strom.navrat,0);
    new:=true;
    optionsDelete:=tempDelete;
    edit1.Clear;
  end;
  if (Key='r') OR (Key='R') then begin //random
    randomize();
    _random:= random(200)+1;
    if strom.vloz(_random) then begin
        strom.Back(_random,0);
        new:=false;
    end;
    edit1.Clear; 
  end;
end;


procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if not(checkInteger(edit1.text)) then
    edit1.Clear
end;


procedure TForm1.Load1Click(Sender: TObject);
begin
  opendialog1.InitialDir:=path;
  if opendialog1.Execute  then begin
    strom.load(opendialog1.FileName);
  end;
  edit1.Clear;
end;

procedure TForm1.N11Click(Sender: TObject);
begin
  N11.Checked:=true;
  N21.Checked:=false;
  N31.Checked:=false;
  N41.Checked:=false;
  N51.Checked:=false;
  strom.setAnimationSpeed(1);
end;

procedure TForm1.N21Click(Sender: TObject);
begin
  N21.Checked:=true;
  N11.Checked:=false;
  N31.Checked:=false;
  N41.Checked:=false;
  N51.Checked:=false;
  strom.setAnimationSpeed(2);
end;

procedure TForm1.N31Click(Sender: TObject);
begin
  N31.Checked:=true;
  N11.Checked:=false;
  N21.Checked:=false;
  N41.Checked:=false;
  N51.Checked:=false;
  strom.setAnimationSpeed(3);
end;

procedure TForm1.N41Click(Sender: TObject);
begin
  N41.Checked:=true;
  N11.Checked:=false;
  N21.Checked:=false;
  N31.Checked:=false;
  N51.Checked:=false;
  strom.setAnimationSpeed(4);
end;

procedure TForm1.N51Click(Sender: TObject);
begin
  N51.Checked:=true;
  N11.Checked:=false;
  N21.Checked:=false;
  N31.Checked:=false;
  N41.Checked:=false;
  strom.setAnimationSpeed(5);
end;

procedure TForm1.NahradMaxZLava1Click(Sender: TObject);
begin
  NahradMaxZLava1.Checked:=true;
  NahradMinZPrava1.Checked:=false;
  if new then begin
    optionsDelete:=1; //pri vymazavanim nahradzam max z lava
    tempDelete:=1;
  end
  else
    tempDelete:=1;
  if length(strom.navrat)>0 then
    ShowMessage('Changes will take effect after creating a new tree!');
end;

procedure TForm1.NahradMinZPrava1Click(Sender: TObject);
begin
  NahradMaxZLava1.Checked:=false;
  NahradMinZPrava1.Checked:=true;
  if new then begin
    optionsDelete:=2; //pri vymazavanim nahradzam min z prava
    tempDelete:=2;
  end
  else
    tempDelete:=2;
  if length(strom.navrat)>0 then
    ShowMessage('Changes will take effect after creating a new tree!');
end;

procedure TForm1.NewTree1Click(Sender: TObject);
begin
  strom.clear;
  setlength(strom.navrat,0);
  new:=true;
  optionsDelete:=tempDelete;
  edit1.Clear;
end;

procedure TForm1.Noanimation1Click(Sender: TObject);
begin
  Noanimation1.Checked:=true;
  Krokom1.Checked:=false;
  Animacia1.Checked:=false;
  Speed1.Visible:=false;
  strom.setAnimation(1);
end;

procedure TForm1.Close1Click(Sender: TObject);
begin
  application.Terminate;
end;


procedure TForm1.About1Click(Sender: TObject);
begin
  Form2.Left:=Image1.Left+Image1.Width div 2 - Form2.Width div 2;
  Form2.Top:=Image1.Top+Image1.Height div 2 - Form2.Height div 2;
  Form2.ShowModal;
end;

procedure TForm1.Save1Click(Sender: TObject);
begin
    savedialog1.InitialDir:=path;
    if (length(strom.navrat)>0) AND (savedialog1.Execute)  then
      strom.save(optionsDelete,savedialog1.FileName)
    else
      ShowMessage('Empty Tree cannot save');
    edit1.Clear;
end;



procedure TForm1.SpeedButton1Click(Sender: TObject);  //pridanie vrcholu
var
  isInt : boolean;
begin
    if edit1.Text<>'' then begin
      isInt:=checkInteger(edit1.text);
      if isInt then begin
        if strtoint(edit1.text)>200 then begin
          ShowMessage('Too big Input');
          strom.kresli;
        end
        else begin
          timer1.Enabled:=true;
          if (strtoint(edit1.text)>0) AND (strom.vloz(strtoint(edit1.text))) then begin
            strom.Back(strtoint(edit1.text),0);
            new:=false;
          end;
          timer1.Enabled:=false;
        end;
      end
      else
        ShowMessage('Bad input');
      edit1.Clear;
    end else
      ShowMessage('Bad input');
end;

procedure TForm1.SpeedButton2Click(Sender: TObject);  //pridanie nahodneho vrcholu
var
  _random: integer;
begin
    randomize();
    _random:= random(200)+1;
    if strom.vloz(_random) then
        strom.Back(_random,0);
    new:=false;
    edit1.Clear;
end;


procedure TForm1.SpeedButton4Click(Sender: TObject);
begin
    Image1.Canvas.Font.Size:=10;
    Image1.Canvas.Brush.Color:=clWhite;
    Image1.Canvas.Font.Color:=clBlue;
    Image1.Canvas.TextOut(10,10,'Inorder: '+strom.Inorder);
    Image1.Canvas.Font.Color:=clGreen;
    Image1.Canvas.TextOut(10,30,'Postorder: '+strom.Postorder);
    Image1.Canvas.Font.Color:=clRed;
    Image1.Canvas.TextOut(10,50,'Preorder: '+strom.Preorder);
end;

procedure TForm1.SpeedButton5Click(Sender: TObject);
var
  temp: integer;
begin
    if edit1.Text<>'' then begin
      if (strtoint(edit1.text)>0) AND
         (strom.Zrus(optionsDelete,strtoint(edit1.text))) then
        strom.Back(-1*strtoint(edit1.text),0);
      edit1.Clear;
    end else
      ShowMessage('Bad input');
end;

procedure TForm1.SpeedButton6Click(Sender: TObject);
var
  temp: integer;
begin
  temp:=strom.setAnimation(1);
  strom.Back(0,optionsDelete);
  strom.kresli;
  strom.setAnimation(temp);
  edit1.clear;
end;

procedure TForm1.SpeedButton7Click(Sender: TObject);
begin
  if edit1.Text<>'' then begin
    if checkInteger(edit1.text) then
      strom.Hladaj(strtoint(edit1.text)) else
      ShowMessage('Bad input');
    edit1.Clear;
  end else
    ShowMessage('Bad input');
end;



procedure TForm1.Settings;
begin
    // FULLSCREEN
    Form1.BorderStyle := bsNone;
 //   Form1.FormStyle   := fsStayOnTop;
    Form1.Left:= 0;
    Form1.Top:= 0;
    Form1.Height:= Screen.Height;
    Form1.Width:= Screen.Width;
    DoubleBuffered:=true;
    //Vycistenie editov. labelov, mema
    edit1.Clear;
    //Nastavenie pozicie komponentov
    Image1.Width:= Screen.Width - 300;
    Image1.Height:= Screen.Height - 50;
    Image1.Top:=((Form1.Top+Form1.Height) div 2) - (Image1.Height div 2)-10;
    Image1.Left:=10;
    Edit1.Width:= 50;
    Edit1.Height:= 20;
    Edit1.Top:=20;
    Edit1.Left:=Image1.Left+ Image1.Width+120;
    SpeedButton1.Width:= 100;
    SpeedButton1.Height:= 30;
    SpeedButton1.Top:=Edit1.Top+ Edit1.Height+ 5;
    SpeedButton1.Left:= Image1.Left+ Image1.Width+ 30;
    SpeedButton5.Width:=100;
    SpeedButton5.Height:=30;
    SpeedButton5.Left:= SpeedButton1.Left+ SpeedButton1.Width+ 30;
    SpeedButton5.Top:=  SpeedButton1.Top;
    SpeedButton2.Width:= 100;
    SpeedButton2.Height:= 30;
    SpeedButton2.Top:=SpeedButton1.Top+ SpeedButton1.Height+ 20;
    SpeedButton2.Left:= Image1.Left+ Image1.Width+100;
    SpeedButton6.Width:=100;
    SpeedButton6.Height:=30;
    SpeedButton6.Left:= Image1.Left+ Image1.Width+ 30;
    SpeedButton6.Top:=SpeedButton2.Top+ SpeedButton2.Height+20;
    SpeedButton7.Width:=100;
    SpeedButton7.Height:=30;
    SpeedButton7.Left:= SpeedButton6.Left+ SpeedButton6.Width+ 30;
    SpeedButton7.Top:=SpeedButton6.Top;
    SpeedButton4.Width:=100;
    SpeedButton4.Height:=30;
    SpeedButton4.Left:= Image1.Left+ Image1.Width+100;
    SpeedButton4.Top:= SpeedButton6.Top+ SpeedButton6.Height+20;
    OpenDialog1.DefaultExt := 'avl';
    OpenDialog1.FileName := '';
    OpenDialog1.Filter := 'AVL files (*.avl)|*.avl';
    SaveDialog1.DefaultExt := 'avl';
    SaveDialog1.FileName := '';
    SaveDialog1.Filter := 'AVL files (*.avl)|*.avl';
    Speed1.Visible:=false;
end;

end.
